<template>
	<a-select v-model:value="values" v-bind="option">
		<template #dropdownRender="{menuNode}">
			<div class="area-wrapper" @click.stop>
				<div class="city-container">
					<component :is="menuNode" />
				</div>
				<div class="area-container">
					<a-skeleton :loading="loadings.area" active :paragraph="{rows: 7}">
						<template v-if="areas.length">
							<template v-for="item in areas" :key="item.id">
								<div :class="['ant-select-item', 'ant-select-item-option', item.class]" :title="item.name" @click="areaChange(item)">
									{{ item.name }}
								</div>
							</template>
						</template>
						<a-empty v-else class="house-empty ant-empty-small" :image="Empty.PRESENTED_IMAGE_SIMPLE" />
					</a-skeleton>
				</div>
				<div class="town-container">
					<a-skeleton :loading="loadings.town" active :paragraph="{rows: 7}">
						<template v-if="towns.length">
							<template v-for="item in towns" :key="item.id">
								<div :class="['ant-select-item', 'ant-select-item-option', item.class]" :title="item.name" @click="townChange(item)">
									{{ item.name }}
								</div>
							</template>
						</template>
						<a-empty v-else class="house-empty ant-empty-small" :image="Empty.PRESENTED_IMAGE_SIMPLE" />
					</a-skeleton>
				</div>
			</div>
		</template>
	</a-select>
</template>

<script lang="ts" setup>
	import {computed, onMounted, reactive, ref, toRef} from 'vue'
	import settingApi from 'yuxin-base/src/api/setting-api'
	import XEUtils from 'xe-utils'
	import {Empty} from 'ant-design-vue'

	const props = defineProps<{
		provinceId?: string
		cityId?: string
		areaId?: string
		townId?: string
		// 占位提示
		placeholder?: string
	}>()

	const areas = ref<any[]>([])
	const towns = ref<any[]>([])

	const values = computed({
		get() {
			const ids = [props.provinceId, props.cityId, props.areaId, props.townId].filter(id => id).reverse()

			XEUtils.eachTree(option.options, item => {
				item.class = ids.includes(item.id) ? 'ant-select-item-option-selected' : ''
			})

			const {nodes} = XEUtils.findTree(option.options, (item: any) => item.id === ids[0]) || {nodes: []}
			const names = nodes.map(o => o.name)
			return XEUtils.union(names).join('/') || null
		},
		set(value) {
			if (value !== props.cityId) {
				const {item, nodes} = XEUtils.findTree(option.options, (item: any) => item.id === value) || {nodes: [{id: null}]}

				if (value) {
					towns.value = []
					if (item.children) {
						areas.value = item.children
					} else {
						loadings.area = true
						settingApi
							.getAreaListByCityId(value)
							.then(({data = []}) => {
								data.forEach((o: any) => (o.pid = value))
								item.children = areas.value = data
							})
							.finally(() => (loadings.area = false))
					}
				}

				emits('update:provinceId', nodes[0].id)
				emits('update:cityId', value || null)
				emits('update:areaId', null)
				emits('update:townId', null)
				emits('change')
			}
		}
	})

	const loadings = reactive({
		area: false,
		town: false
	})

	const emits = defineEmits(['update:provinceId', 'update:cityId', 'update:areaId', 'update:townId', 'change'])
	const option = reactive<any>({
		open: false,
		options: [],
		allowClear: true,
		showSearch: true,
		listHeight: 300,
		optionFilterProp: 'name',
		maxTagCount: 'responsive',
		fieldNames: {
			label: 'name',
			value: 'id',
			key: 'id',
			children: 'children',
			options: 'children'
		},
		dropdownMatchSelectWidth: 600,
		placeholder: toRef(props, 'placeholder', '请选择城市、区域、乡镇'),
		// mode: 'multiple',
		dropdownClassName: 'area-select-dropdown',
		onDropdownVisibleChange() {
			if (event && event.type !== 'click') {
				option.open = !option.open
			} else {
				option.open = true
			}
		}
	})

	onMounted(() => settingApi.getCityList().then(({data}) => (option.options = data)))

	const areaChange = (area: any) => {
		if (area.id !== props.areaId) {
			const {nodes} = XEUtils.findTree(option.options, (item: any) => item.id === area.id)

			emits('update:provinceId', nodes[0].id)
			emits('update:cityId', nodes[1].id)
			emits('update:areaId', area.id)
			emits('update:townId', null)
			emits('change')

			if (area.children) {
				towns.value = area.children
			} else {
				loadings.town = true
				settingApi
					.getTownListByAreaId(area.id)
					.then(({data = []}) => {
						data.forEach((o: any) => (o.pid = area.id))
						area.children = towns.value = data
					})
					.finally(() => (loadings.town = false))
			}
		}
	}

	const townChange = (town: any) => {
		if (town.id !== props.townId) {
			const {nodes} = XEUtils.findTree(option.options, (item: any) => item.id === town.id)

			emits('update:provinceId', nodes[0].id)
			emits('update:cityId', nodes[1].id)
			emits('update:areaId', nodes[2].id)
			emits('update:townId', town.id)
			emits('change')
		}
	}
</script>

<style lang="less">
	.area-select-dropdown {
		.area-wrapper {
			display: flex;
			max-height: 300px;

			> div {
				flex: 1;
			}

			.area-container,
			.town-container {
				overflow: auto;
				border-left: 2px solid #ecf0f9;

				.ant-skeleton {
					padding: 0 12px;
				}

				.ant-select-item:hover {
					background-color: #f5f5f5;
				}
			}
		}
	}
</style>
